package com.tangula.voicenote.view

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.media.MediaPlayer
import android.media.MediaRecorder
import android.os.Environment
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.*
import com.tangula.android.utils.ApplicationUtils
import com.tangula.android.utils.TaskUtils
import com.tangula.android.utils.ToastUtils
import com.tangula.voicenote.service.AddOverlayService
import com.tangula.voicenote.R
import com.tangula.voicenote.VoiceNoteApplication
import com.tangula.voicenote.adapter.ListViewAdapter
import com.tangula.voicenote.entity.NoticeEntity
import com.tangula.voicenote.entity.ToolsEntity
import com.tangula.voicenote.service.DatabaseService
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat

@SuppressLint("ClickableViewAccessibility")
class NoteViewHolder(val notice: NoticeEntity) {

    companion object {
        fun noticeColor2LayoutResId(color: Int): Int {
            return when (color) {
                1 -> R.layout.layout_note_blue
                2 -> R.layout.layout_note_dark_cyan
                3 -> R.layout.layout_note_dark_green
                4 -> R.layout.layout_note_gray
                5 -> R.layout.layout_note_green
                6 -> R.layout.layout_note_oryal_blue
                7 -> R.layout.layout_note_purple
                8 -> R.layout.layout_note_red
                9 -> R.layout.layout_note_yellow
                else -> R.layout.layout_note_aqua
            }
        }

        fun noticeColor2DockerLayoutResId(color: Int): Int {
            return when (color) {
                1 -> R.layout.layout_note_blue_docker
                2 -> R.layout.layout_note_dark_cyan_docker
                3 -> R.layout.layout_note_dark_green_docker
                4 -> R.layout.layout_note_gray_docker
                5 -> R.layout.layout_note_green_docker
                6 -> R.layout.layout_note_oryal_blue_docker
                7 -> R.layout.layout_note_purple_docker
                8 -> R.layout.layout_note_red_docker
                9 -> R.layout.layout_note_yellow_docker
                else -> R.layout.layout_note_aqua_docker
            }
        }
    }

    lateinit var view: View
    lateinit var dir: String
    lateinit var fullAudioPath: String

    lateinit var sound: ImageView
    lateinit var nosound: ImageView
    lateinit var hold: Button

    lateinit var duration: Button
    lateinit var text: EditText
    lateinit var list: ListView

    init {

        view = LayoutInflater.from(ApplicationUtils.APP)
            .inflate(noticeColor2LayoutResId(notice.color % VoiceNoteApplication.COLOR_COUNT), null)




        dir =
                "${Environment.getExternalStorageDirectory().absolutePath}${File.separator}${ApplicationUtils.APP.packageName}${File.separator}audios"

        File(dir).apply {
            if (!exists()) {
                mkdirs()
            }
        }
        fullAudioPath =
                "${dir}${File.separator}${notice.id}.3gp"

        list = initNoteTools()
        initAddButton()
        initCloseButton()
        initDownButton()
        initText()
        initHoldButton()
        initDurationButton()
        sound = initSoundButton()
        nosound = initNoSoundButton()


    }

    private fun formatSeconds(ss: Int): String {
        return when {
            ss in 1..1000 -> {
                "00:00:01"
            }
            ss <= 0 -> "00:00:00"
            else ->
                SimpleDateFormat("HH:mm:ss").run {
                    val date = parse("00:00:00")
                    date.time = date.time - if (date.time % 1000 > 0) 1000 else 0
                    date.time += ss
                    format(date)
                }
        }
    }

    private fun initDurationButton(): Button {
        return view.findViewById<Button>(R.id.vw_duration_button).apply {

            File(fullAudioPath).also { file ->
                if (file.exists()) {
                    MediaPlayer().apply {
                        Log.v("console", "file play time:" + this.duration)
                        this.setDataSource(fullAudioPath)
                        prepare()
                        text = formatSeconds(this.duration)
                        release()
                    }
                    visibility = View.VISIBLE
                } else {
                    visibility = View.GONE
                }
            }

            setOnClickListener {

                val mMediaPlayer = MediaPlayer()

                if (mMediaPlayer.isPlaying) {
                    mMediaPlayer.stop()
                }
                mMediaPlayer.reset()
                try {
                    mMediaPlayer.setDataSource(fullAudioPath)
                    mMediaPlayer.prepare()
                    mMediaPlayer.start()

                    mMediaPlayer.setOnCompletionListener {
                        it.release()
                    }

                } catch (e: IOException) {
                    Log.e("console", e.localizedMessage, e)
                }
            }

            duration = this
        }

    }

    private fun initHoldButton() {

        hold = view.findViewById(R.id.vw_hold_to_talk_button)
        hold.visibility = if (notice.noteType != 0) View.VISIBLE else View.GONE

        //new出录音对象
        lateinit var mRecoder: MediaRecorder
        var startTm = 0L
        hold.setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {

                    mRecoder = MediaRecorder()
                    //设置Audio的音频源为麦克风
                    mRecoder.setAudioSource(MediaRecorder.AudioSource.MIC)
                    //设置Audio录音的音频模式(输出格式)
                    //  mRecoder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                    //   mRecoder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
                    // mRecoder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB)
                    mRecoder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
                    //设置Audio录制音频的编码为AMR
                    mRecoder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
                    //设置录制的音频的存储路径
                    mRecoder.setOutputFile(fullAudioPath)

                    try {
                        mRecoder.prepare()
                        mRecoder.start()
                        startTm = System.currentTimeMillis()
                        hold.text = "Speaking"
                        duration.text = "recording"
                    } catch (e: Exception) {
                        Log.e("console", e.localizedMessage, e)
                    }
                }
                MotionEvent.ACTION_MOVE -> {
                }
                MotionEvent.ACTION_UP -> {
                    try {
                        mRecoder.stop()
                        Log.v("console", "record stop:${System.currentTimeMillis() - startTm}")
                        initDurationButton()
                    } catch (e: Throwable) {
                        Log.e("console", e.localizedMessage, e)
                    } finally {
                        mRecoder.release()
                        hold.text = "HOLD TO TALK"
                    }
                }
            }
            return@setOnTouchListener true
        }

    }

    fun initNoteTools(): ListView {
        return view.findViewById<ListView>(R.id.vw_list).apply {
            val toolsDate = ToolsEntity.getAllTools()
            adapter = ListViewAdapter(view.context, R.layout.item_list, toolsDate)
            isFocusable = true
            isFocusableInTouchMode = true

            val mClipboardManager = ApplicationUtils.APP.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager

            setOnItemClickListener { p, vw, item, id ->
                Log.v("console", "item: ${item}")
                when (item) {
                    0 -> {
                        if (text!!.text.isNotEmpty()) {
                            val mClipData = ClipData.newPlainText("note", text!!.text)
                            mClipboardManager.setPrimaryClip(mClipData);
                            ToastUtils.showToastResLong(R.string.toast_copy_message)
                        } else {
                            ToastUtils.showToastResLong(R.string.toast_message_is_blank)
                        }
                        visibility = View.GONE
                    }
                    1 -> {
                        val date: ClipData = mClipboardManager.primaryClip
                        val item: ClipData.Item = date.getItemAt(0)
                        val context = item.text.toString()
                        text!!.text.append(context)
                        visibility = View.GONE
                    }
                    2 -> {
                        TaskUtils.runInUiThread {
                            val intent = Intent(Intent.ACTION_SEND)
                            intent.type = "text/plain"
                            intent.putExtra(Intent.EXTRA_SUBJECT, ApplicationUtils.APP.getString(R.string.title_share))
                            intent.putExtra(Intent.EXTRA_TEXT, text!!.text.toString())
                            ApplicationUtils.APP.startActivity(Intent.createChooser(intent, ApplicationUtils.APP.getString(R.string.title_share)).apply{
                                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            })
                        }
                        visibility = View.GONE
                    }
                    3 -> {
                        visibility = View.GONE
                    }
                    4 -> {
                        visibility = View.GONE
                    }
                }
            }


            visibility = View.GONE
            //requestFocus()
        }
    }

    fun initAddButton(): ImageView {
        return view.findViewById<ImageView>(R.id.vw_img_add).apply {
            setImageResource(R.mipmap.add)
            setOnClickListener {
                TaskUtils.runInBackground {
                    DatabaseService.exec { db ->
                        val newer = db.createNotice()
                        newer.top = notice.top + 100
                        newer.left = notice.left + 100
                        db.saveNotice(newer)
                        AddOverlayService.addOverlayServiceById(newer.id)
                    }
                }
            }
        }
    }

    fun initCloseButton(): ImageView {
        return view.findViewById<ImageView>(R.id.vw_img_close).apply {
            setImageResource(R.mipmap.close)
            setOnClickListener {
                AddOverlayService.removeOverlayService(notice)
            }
        }
    }

    fun initDownButton(): ImageView {
        return view.findViewById<ImageView>(R.id.vw_img_down).apply {
            setImageResource(R.mipmap.down)
            setOnClickListener {
                Log.v("console", "click down")
                if (list.visibility == View.VISIBLE) {
                    list.visibility = View.GONE
                } else {
                    list.visibility = View.VISIBLE
                    list.requestFocus()
                }
            }
        }
    }


    fun initSoundButton(): ImageView {
        return view.findViewById<ImageView>(R.id.vw_img_sound).apply {
            setImageResource(R.mipmap.sound)
            visibility = if (notice.noteType == 0) View.VISIBLE else View.GONE
            setOnClickListener {

                notice.noteType = 1
                notice.b64voice = fullAudioPath

                TaskUtils.runInBackground {
                    DatabaseService.exec { db ->
                        db.saveNotice(notice)
                        TaskUtils.runInUiThread {
                            visibility = View.GONE
                            nosound.visibility = View.VISIBLE
                            hold.visibility = View.VISIBLE
                            Unit
                        }
                    }
                }

            }
        }
    }

    fun initNoSoundButton(): ImageView {
        return view.findViewById<ImageView>(R.id.vw_img_nosound).apply {
            setImageResource(R.mipmap.nosound)
            visibility = if (notice.noteType != 0) View.VISIBLE else View.GONE

            setOnClickListener {
                notice.noteType = 0

                TaskUtils.runInBackground {
                    DatabaseService.exec { db ->

                        File(notice.b64voice).delete()

                        notice.b64voice = ""
                        db.saveNotice(notice)
                        TaskUtils.runInUiThread {
                            sound.visibility = View.VISIBLE
                            visibility = View.GONE
                            hold.visibility = View.GONE
                            duration.visibility = View.GONE
                            Unit
                        }
                    }
                }

            }

        }
    }

    fun initText(): EditText {
        text = view.findViewById(R.id.editText)
        text.setText(notice.message.toCharArray(), 0, notice.message.length)

        text.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                notice.message = s.toString()
                TaskUtils.runInBackground {
                    DatabaseService.exec { db ->
                        db.saveNotice(notice)
                    }
                }
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }
        })
        return text
    }
}